package cn.lg.soar.common.util.trans.handler;

import cn.lg.soar.common.util.data.DataUtil;
import cn.lg.soar.common.util.trans.TranslateHelpUtils;
import cn.lg.soar.common.util.trans.annotations.TranslateByString;
import cn.lg.soar.common.util.trans.model.TranslateContext;
import org.springframework.util.ConcurrentReferenceHashMap;

import java.lang.annotation.Annotation;
import java.util.HashMap;
import java.util.Map;

/**
 * @author luguoxiang
 * @date 2022/6/11
 * 开源项目：https://gitee.com/lgx1992/lg-soar 求star！请给我star！请帮我点个star！
 */
public class TranslateByStringHandler implements ITranslateHandler<Object> {

    private final static Map<Annotation, Map<String, String>> CACHE = new ConcurrentReferenceHashMap<>(64);
    private final static Map<Annotation, Map<String, String>> TOJAVA_CACHE = new ConcurrentReferenceHashMap<>(64);

    protected Map<String, String> getMap(Annotation annotation) {
        TranslateByString translate = (TranslateByString) annotation;
        String[] values = translate.value();
        if (values.length == 1 && DataUtil.isValuable(translate.separator())) {
            values = values[0].split(translate.separator());
        }
        Map<String, String> map = new HashMap<>(values.length);
        for (String item : values) {
            int i = item.indexOf(":");
            map.put(item.substring(0, i), item.substring(i + 1));
        }
        return map;
    }

    @Override
    public Object convertByJava(Object javaValue, Annotation annotation, TranslateContext<Object> context) {
        Map<String, String> map = CACHE.computeIfAbsent(annotation, this::getMap);
        String text = map.get(javaValue.toString());
        if (text != null) {
            return text;
        }
        return TranslateHelpUtils.mapper(javaValue, k -> {
            if (k == null) {
                return null;
            }
            return map.get(k.toString());
        });
    }

    @Override
    public Object convertToJava(Object value, Annotation annotation, TranslateContext<Object> context) {
        Map<String, String> map = TOJAVA_CACHE.computeIfAbsent(annotation, key -> {
            Map<String, String> map1 = CACHE.computeIfAbsent(annotation, this::getMap);
            Map<String, String> rmap = new HashMap<>(map1.size());
            map1.forEach((k, v) -> rmap.put(v, k));
            return rmap;
        });

        Class<?> javaType = context.getJavaType();
        String strValue = value.toString();
        Object o = map.get(strValue);
        if (o != null) {
            return DataUtil.to(javaType, o);
        }
        o = TranslateHelpUtils.remapper(javaType, strValue, map::get);
        if (o != null) {
            return o;
        }
        return null;
    }
}
